package com.school.sports.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.school.sports.entity.ExceptionRecord;
import com.school.sports.service.ExceptionHandlingService;
import com.school.sports.common.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 异常处理控制器
 * 提供异常记录查询、处理、统计、报告等功能
 */
@RestController
@RequestMapping("/api/exceptions")
public class ExceptionHandlingController {

    private static final Logger logger = LoggerFactory.getLogger(ExceptionHandlingController.class);

    @Autowired
    private ExceptionHandlingService exceptionHandlingService;

    /**
     * 分页查询异常记录
     * @param currentPage 当前页码
     * @param pageSize 每页大小
     * @param exceptionRecord 查询条件
     * @return 分页结果
     */
    @GetMapping("/page/{currentPage}/{pageSize}")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<IPage<ExceptionRecord>> getExceptionRecordPage(
            @PathVariable("currentPage") Integer currentPage,
            @PathVariable("pageSize") Integer pageSize,
            ExceptionRecord exceptionRecord) {

        logger.info("分页查询异常记录，当前页码：{}，每页条数：{}，查询条件：{}", currentPage, pageSize, exceptionRecord);

        // 参数校验
        if (currentPage == null || currentPage <= 0) {
            currentPage = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 10;
        }

        try {
            IPage<ExceptionRecord> page = exceptionHandlingService.getExceptionRecordPage(currentPage, pageSize, exceptionRecord);
            logger.info("查询异常记录成功，共{}条记录", page.getTotal());
            return Result.success(page);
        } catch (Exception e) {
            logger.error("查询异常记录异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 根据ID查询异常记录详情
     * @param recordId 记录ID
     * @return 异常记录详情
     */
    @GetMapping("/{recordId}")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<ExceptionRecord> getExceptionRecordById(@PathVariable("recordId") Long recordId) {
        logger.info("查询异常记录详情，记录ID：{}", recordId);

        if (recordId == null || recordId <= 0) {
            return Result.fail("记录ID无效");
        }

        try {
            ExceptionRecord record = exceptionHandlingService.getExceptionRecordById(recordId);
            if (record == null) {
                return Result.fail("异常记录不存在");
            }
            logger.info("查询异常记录详情成功，异常类型：{}", record.getExceptionType());
            return Result.success(record);
        } catch (Exception e) {
            logger.error("查询异常记录详情异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 处理异常记录
     * @param recordId 记录ID
     * @param handlerId 处理人ID
     * @param handlerName 处理人姓名
     * @param solution 解决方案
     * @return 操作结果
     */
    @PutMapping("/{recordId}/handle")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<String> handleExceptionRecord(
            @PathVariable("recordId") Long recordId,
            @RequestParam("handlerId") Long handlerId,
            @RequestParam("handlerName") String handlerName,
            @RequestParam("solution") String solution) {

        logger.info("处理异常记录，记录ID：{}，处理人：{}", recordId, handlerName);

        if (recordId == null || recordId <= 0) {
            return Result.fail("记录ID无效");
        }

        if (handlerId == null || handlerId <= 0) {
            return Result.fail("处理人ID无效");
        }

        if (!org.springframework.util.StringUtils.hasText(handlerName)) {
            return Result.fail("处理人姓名不能为空");
        }

        if (!org.springframework.util.StringUtils.hasText(solution)) {
            return Result.fail("解决方案不能为空");
        }

        try {
            boolean success = exceptionHandlingService.handleExceptionRecord(recordId, handlerId, handlerName, solution);
            if (success) {
                logger.info("处理异常记录成功：{}", recordId);
                return Result.success("处理成功");
            } else {
                return Result.fail("处理失败");
            }
        } catch (Exception e) {
            logger.error("处理异常记录异常：{}", e.getMessage(), e);
            return Result.fail("处理失败：" + e.getMessage());
        }
    }

    /**
     * 批量处理异常记录
     * @param request 请求参数
     * @return 操作结果
     */
    @PutMapping("/batch-handle")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<String> batchHandleExceptionRecords(@RequestBody Map<String, Object> request) {
        logger.info("批量处理异常记录");

        @SuppressWarnings("unchecked")
        List<Long> recordIds = (List<Long>) request.get("recordIds");
        Long handlerId = (Long) request.get("handlerId");
        String handlerName = (String) request.get("handlerName");
        String solution = (String) request.get("solution");

        if (recordIds == null || recordIds.isEmpty()) {
            return Result.fail("请选择要处理的异常记录");
        }

        if (handlerId == null || handlerId <= 0) {
            return Result.fail("处理人ID无效");
        }

        if (!org.springframework.util.StringUtils.hasText(handlerName)) {
            return Result.fail("处理人姓名不能为空");
        }

        if (!org.springframework.util.StringUtils.hasText(solution)) {
            return Result.fail("解决方案不能为空");
        }

        try {
            boolean success = exceptionHandlingService.batchHandleExceptionRecords(recordIds, handlerId, handlerName, solution);
            if (success) {
                logger.info("批量处理异常记录成功，共{}条记录", recordIds.size());
                return Result.success("批量处理成功");
            } else {
                return Result.fail("批量处理失败");
            }
        } catch (Exception e) {
            logger.error("批量处理异常记录异常：{}", e.getMessage(), e);
            return Result.fail("批量处理失败：" + e.getMessage());
        }
    }

    /**
     * 忽略异常记录
     * @param recordId 记录ID
     * @param handlerId 处理人ID
     * @param handlerName 处理人姓名
     * @param reason 忽略原因
     * @return 操作结果
     */
    @PutMapping("/{recordId}/ignore")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<String> ignoreExceptionRecord(
            @PathVariable("recordId") Long recordId,
            @RequestParam("handlerId") Long handlerId,
            @RequestParam("handlerName") String handlerName,
            @RequestParam("reason") String reason) {

        logger.info("忽略异常记录，记录ID：{}，处理人：{}", recordId, handlerName);

        if (recordId == null || recordId <= 0) {
            return Result.fail("记录ID无效");
        }

        if (handlerId == null || handlerId <= 0) {
            return Result.fail("处理人ID无效");
        }

        if (!org.springframework.util.StringUtils.hasText(handlerName)) {
            return Result.fail("处理人姓名不能为空");
        }

        if (!org.springframework.util.StringUtils.hasText(reason)) {
            return Result.fail("忽略原因不能为空");
        }

        try {
            boolean success = exceptionHandlingService.ignoreExceptionRecord(recordId, handlerId, handlerName, reason);
            if (success) {
                logger.info("忽略异常记录成功：{}", recordId);
                return Result.success("忽略成功");
            } else {
                return Result.fail("忽略失败");
            }
        } catch (Exception e) {
            logger.error("忽略异常记录异常：{}", e.getMessage(), e);
            return Result.fail("忽略失败：" + e.getMessage());
        }
    }

    /**
     * 批量忽略异常记录
     * @param request 请求参数
     * @return 操作结果
     */
    @PutMapping("/batch-ignore")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<String> batchIgnoreExceptionRecords(@RequestBody Map<String, Object> request) {
        logger.info("批量忽略异常记录");

        @SuppressWarnings("unchecked")
        List<Long> recordIds = (List<Long>) request.get("recordIds");
        Long handlerId = (Long) request.get("handlerId");
        String handlerName = (String) request.get("handlerName");
        String reason = (String) request.get("reason");

        if (recordIds == null || recordIds.isEmpty()) {
            return Result.fail("请选择要忽略的异常记录");
        }

        if (handlerId == null || handlerId <= 0) {
            return Result.fail("处理人ID无效");
        }

        if (!org.springframework.util.StringUtils.hasText(handlerName)) {
            return Result.fail("处理人姓名不能为空");
        }

        if (!org.springframework.util.StringUtils.hasText(reason)) {
            return Result.fail("忽略原因不能为空");
        }

        try {
            boolean success = exceptionHandlingService.batchIgnoreExceptionRecords(recordIds, handlerId, handlerName, reason);
            if (success) {
                logger.info("批量忽略异常记录成功，共{}条记录", recordIds.size());
                return Result.success("批量忽略成功");
            } else {
                return Result.fail("批量忽略失败");
            }
        } catch (Exception e) {
            logger.error("批量忽略异常记录异常：{}", e.getMessage(), e);
            return Result.fail("批量忽略失败：" + e.getMessage());
        }
    }

    /**
     * 异常统计分析
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 统计结果
     */
    @GetMapping("/statistics")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<Map<String, Object>> getExceptionStatistics(
            @RequestParam(value = "startTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {

        logger.info("获取异常统计数据，时间范围：{} - {}", startTime, endTime);

        try {
            Map<String, Object> statistics = exceptionHandlingService.getExceptionStatistics(startTime, endTime);
            logger.info("获取异常统计数据成功");
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("获取异常统计数据异常：{}", e.getMessage(), e);
            return Result.fail("获取统计数据失败：" + e.getMessage());
        }
    }

    /**
     * 按异常类型统计
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 统计结果
     */
    @GetMapping("/statistics/by-type")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<List<Map<String, Object>>> getExceptionStatisticsByType(
            @RequestParam(value = "startTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {

        logger.info("按异常类型统计，时间范围：{} - {}", startTime, endTime);

        try {
            List<Map<String, Object>> statistics = exceptionHandlingService.getExceptionStatisticsByType(startTime, endTime);
            logger.info("按异常类型统计成功，共{}种类型", statistics.size());
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("按异常类型统计异常：{}", e.getMessage(), e);
            return Result.fail("统计失败：" + e.getMessage());
        }
    }

    /**
     * 按异常级别统计
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 统计结果
     */
    @GetMapping("/statistics/by-level")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<List<Map<String, Object>>> getExceptionStatisticsByLevel(
            @RequestParam(value = "startTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {

        logger.info("按异常级别统计，时间范围：{} - {}", startTime, endTime);

        try {
            List<Map<String, Object>> statistics = exceptionHandlingService.getExceptionStatisticsByLevel(startTime, endTime);
            logger.info("按异常级别统计成功，共{}个级别", statistics.size());
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("按异常级别统计异常：{}", e.getMessage(), e);
            return Result.fail("统计失败：" + e.getMessage());
        }
    }

    /**
     * 按发生地点统计
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 统计结果
     */
    @GetMapping("/statistics/by-location")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<List<Map<String, Object>>> getExceptionStatisticsByLocation(
            @RequestParam(value = "startTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {

        logger.info("按发生地点统计，时间范围：{} - {}", startTime, endTime);

        try {
            List<Map<String, Object>> statistics = exceptionHandlingService.getExceptionStatisticsByLocation(startTime, endTime);
            logger.info("按发生地点统计成功，共{}个地点", statistics.size());
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("按发生地点统计异常：{}", e.getMessage(), e);
            return Result.fail("统计失败：" + e.getMessage());
        }
    }

    /**
     * 按处理状态统计
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 统计结果
     */
    @GetMapping("/statistics/by-status")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<List<Map<String, Object>>> getExceptionStatisticsByStatus(
            @RequestParam(value = "startTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {

        logger.info("按处理状态统计，时间范围：{} - {}", startTime, endTime);

        try {
            List<Map<String, Object>> statistics = exceptionHandlingService.getExceptionStatisticsByStatus(startTime, endTime);
            logger.info("按处理状态统计成功，共{}种状态", statistics.size());
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("按处理状态统计异常：{}", e.getMessage(), e);
            return Result.fail("统计失败：" + e.getMessage());
        }
    }

    /**
     * 获取异常趋势数据
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param interval 时间间隔
     * @return 趋势数据
     */
    @GetMapping("/trend")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<List<Map<String, Object>>> getExceptionTrendData(
            @RequestParam(value = "startTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @RequestParam(value = "interval", defaultValue = "day") String interval) {

        logger.info("获取异常趋势数据，时间范围：{} - {}，间隔：{}", startTime, endTime, interval);

        try {
            List<Map<String, Object>> trendData = exceptionHandlingService.getExceptionTrendData(startTime, endTime, interval);
            logger.info("获取异常趋势数据成功，共{}个数据点", trendData.size());
            return Result.success(trendData);
        } catch (Exception e) {
            logger.error("获取异常趋势数据异常：{}", e.getMessage(), e);
            return Result.fail("获取趋势数据失败：" + e.getMessage());
        }
    }

    /**
     * 生成异常报告
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param reportType 报告类型
     * @return 报告数据
     */
    @GetMapping("/report")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<Map<String, Object>> generateExceptionReport(
            @RequestParam(value = "startTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @RequestParam(value = "reportType", defaultValue = "daily") String reportType) {

        logger.info("生成异常报告，时间范围：{} - {}，报告类型：{}", startTime, endTime, reportType);

        try {
            Map<String, Object> report = exceptionHandlingService.generateExceptionReport(startTime, endTime, reportType);
            logger.info("生成异常报告成功");
            return Result.success(report);
        } catch (Exception e) {
            logger.error("生成异常报告异常：{}", e.getMessage(), e);
            return Result.fail("生成报告失败：" + e.getMessage());
        }
    }

    /**
     * 获取待处理的异常记录数量
     * @return 数量
     */
    @GetMapping("/pending-count")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<Long> getPendingExceptionCount() {
        logger.info("获取待处理的异常记录数量");

        try {
            long count = exceptionHandlingService.getPendingExceptionCount();
            logger.info("获取待处理的异常记录数量成功：{}", count);
            return Result.success(count);
        } catch (Exception e) {
            logger.error("获取待处理的异常记录数量异常：{}", e.getMessage(), e);
            return Result.fail("获取数量失败：" + e.getMessage());
        }
    }

    /**
     * 获取严重级别的异常记录数量
     * @return 数量
     */
    @GetMapping("/severe-count")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<Long> getSevereExceptionCount() {
        logger.info("获取严重级别的异常记录数量");

        try {
            long count = exceptionHandlingService.getSevereExceptionCount();
            logger.info("获取严重级别的异常记录数量成功：{}", count);
            return Result.success(count);
        } catch (Exception e) {
            logger.error("获取严重级别的异常记录数量异常：{}", e.getMessage(), e);
            return Result.fail("获取数量失败：" + e.getMessage());
        }
    }

    /**
     * 获取最近异常记录
     * @param limit 限制数量
     * @return 异常记录列表
     */
    @GetMapping("/recent")
    @PreAuthorize("hasAnyRole('管理员', '系统管理员')")
    public Result<List<ExceptionRecord>> getRecentExceptions(
            @RequestParam(value = "limit", defaultValue = "10") Integer limit) {

        logger.info("获取最近异常记录，限制数量：{}", limit);

        try {
            List<ExceptionRecord> exceptions = exceptionHandlingService.getRecentExceptions(limit);
            logger.info("获取最近异常记录成功，共{}条记录", exceptions.size());
            return Result.success(exceptions);
        } catch (Exception e) {
            logger.error("获取最近异常记录异常：{}", e.getMessage(), e);
            return Result.fail("获取记录失败：" + e.getMessage());
        }
    }

    /**
     * 删除异常记录
     * @param recordId 记录ID
     * @return 操作结果
     */
    @DeleteMapping("/{recordId}")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> deleteExceptionRecord(@PathVariable("recordId") Long recordId) {
        logger.info("删除异常记录：{}", recordId);

        if (recordId == null || recordId <= 0) {
            return Result.fail("记录ID无效");
        }

        try {
            boolean success = exceptionHandlingService.deleteExceptionRecord(recordId);
            if (success) {
                logger.info("删除异常记录成功：{}", recordId);
                return Result.success("删除成功");
            } else {
                return Result.fail("删除失败");
            }
        } catch (Exception e) {
            logger.error("删除异常记录异常：{}", e.getMessage(), e);
            return Result.fail("删除失败：" + e.getMessage());
        }
    }

    /**
     * 批量删除异常记录
     * @param recordIds 记录ID列表
     * @return 操作结果
     */
    @DeleteMapping("/batch")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> batchDeleteExceptionRecords(@RequestBody List<Long> recordIds) {
        logger.info("批量删除异常记录：{}", recordIds);

        if (recordIds == null || recordIds.isEmpty()) {
            return Result.fail("请选择要删除的异常记录");
        }

        try {
            boolean success = exceptionHandlingService.batchDeleteExceptionRecords(recordIds);
            if (success) {
                logger.info("批量删除异常记录成功，共{}条记录", recordIds.size());
                return Result.success("批量删除成功");
            } else {
                return Result.fail("批量删除失败");
            }
        } catch (Exception e) {
            logger.error("批量删除异常记录异常：{}", e.getMessage(), e);
            return Result.fail("批量删除失败：" + e.getMessage());
        }
    }

    /**
     * 清理过期的异常记录
     * @param beforeTime 时间点
     * @return 清理数量
     */
    @DeleteMapping("/clean")
    @PreAuthorize("hasRole('管理员')")
    public Result<Integer> cleanExpiredExceptionRecords(
            @RequestParam("beforeTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime beforeTime) {

        logger.info("清理过期的异常记录，清理时间点：{}", beforeTime);

        if (beforeTime == null) {
            return Result.fail("清理时间点不能为空");
        }

        try {
            int count = exceptionHandlingService.cleanExpiredExceptionRecords(beforeTime);
            logger.info("清理过期的异常记录成功，共清理{}条记录", count);
            return Result.success(count);
        } catch (Exception e) {
            logger.error("清理过期的异常记录异常：{}", e.getMessage(), e);
            return Result.fail("清理失败：" + e.getMessage());
        }
    }
}